package mypinger

import (
	"net"
	"time"

	"gitee.com/sillyman/PingHostsWebView/models"
	"gitee.com/sillyman/PingHostsWebView/modules/config"
	"gitee.com/sillyman/PingHostsWebView/modules/db"
)

var (
	// myPingers 保存创建的实例
	myPingers = make(map[string]*myPinger)
)

// StartPingerMgr 启动 Pinger 管理器
// 从 host_config 表格中获取 is_running=true 的主机，然后启动对应的pinger
// 检查已经运行的pinger，如果 is_running=false 则停止此pinger
func MustStartPingerMgr() {
	ticker := time.NewTicker(3 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		hosts := make([]models.HostConfig, 0, 128)

		dbConn := db.MustObtainMainDB()
		if err := dbConn.Where("is_running = ?", true).Limit(config.AllowMaxNumHosts).Find(&hosts).Error; err != nil {
			panic(err)
		}
		db.ReleaseMainDB()

		// 启动和设置pingers
		for _, h := range hosts {
			p, ok := myPingers[h.IP]
			if !ok {
				p = mustCreatePinger(net.ParseIP(h.IP))
				myPingers[h.IP] = p
			}

			p.pingIntervalDur = h.PingIntervalDur
			p.pingTimeout = h.PingTimeout
			p.numberOfMaxRecord = h.NumberOfMaxRecord
			p.pingPayloadSize = h.PingPayloadSize

			if !ok {
				go p.MustStart()
			}
		}

		// 停止pingers
		for ip, p := range myPingers {
			var isExist bool
			for _, h := range hosts {
				if ip == h.IP {
					isExist = true
					break
				}
			}

			if !isExist {
				p.Destroy()
				delete(myPingers, ip)
			}
		}
	}
}

// StopMyPinger 停止pinger
func StopMyPinger(ip net.IP) {
	p, ok := myPingers[ip.String()]
	if ok {
		p.Destroy()
	}
}

// mustCreatePinger 创建一个实例
func mustCreatePinger(ip net.IP) *myPinger {
	// 已经存在
	if p, ok := myPingers[ip.String()]; ok {
		return p
	}

	return &myPinger{
		ipAddr:   &net.IPAddr{IP: ip},
		quitCh:   make(chan bool),
		mydbConn: db.MustOpenPingRecordDB(ip),
	}
}
